#!/usr/bin/env python

from unittest import TestCase, main
import lattice
import numpy
import random
from main import main as MN

class test_lattice( TestCase ):
    '''
    my first testing class. Tests lattice class
    '''
    def test_some_lattice_properties(self):
        h_neighbours = ( (0, 1), (0, -1), (1, 0), (-1, 0) )
        shape = (4, 4)
        h_size = shape[0]
        v_size = 1
        dimension = len(shape)
        ferromagnetic = True
        L = lattice.Lattice( shape , h_neighbours, ferromagnetic, T = 1  )
        self.assertEqual(L.h_size, h_size)
        self.assertEqual(L.v_size, v_size)
        self.assertTrue(L.ferromagnetic, ferromagnetic)
        #checking lattice for values at each site. shoul be equal +1 or -1
        for site in L:
            self.assertEqual(numpy.abs(L.lattice[site]), 1)
            
        #checking __iter__
        ind = 0
        for site in L:
            ind += 1
        
        nSites = numpy.prod(shape)
            
        self.assertEqual(ind, nSites)
        
        #checking flipping
        initial_spin = L.lattice[ (1, 1) ]
        L.lattice[ (1,1 )] *= -1
        self.assertEqual( initial_spin, (-1) * L.lattice[ (1,1) ]  )
        
        #checking dE
        initial_energy = L.Energy()
        
        x, y = random.randint(0, shape[0] - 1), random.randint(0, shape[1] - 1)
        
        L.lattice[ (x,y )] *= -1
        final_energy = L.Energy()
        if ferromagnetic:
            #test for consistency, no logic explanation now for this
            #self.assertEqual( final_energy - initial_energy, 2 * L.lattice[(x,y)] * L.Sum_n_sites( (x,y) ) )
            self.assertEqual( - final_energy + initial_energy, 2 * L.lattice[(x,y)] * L.Sum_h_sites( (x,y) ) )
        else:
            self.assertEqual( final_energy - initial_energy, - 2 * L.lattice[(x,y)] * L.Sum_h_sites( (x,y) ) )
            
        #for ferromagnetic mean Energy at T = 1 should be between -2.1 and -1.9
        tE = MN( 1 )[0]
        if not -2.1 < tE < -1.9:
            self.fail('Energy not in proper range. At temperature = 1 It should be more then -2.1 and less then -1.9. But now we have %f'%tE )
    
        
if __name__ == '__main__':
    main()
